<template>
	<div class="flex h-screen bg-gray-100">
		<!-- Online Users List -->
		<div class="w-1/4 bg-white border-r border-gray-200 overflow-y-auto">
			<h3 class="text-lg font-semibold p-4 border-b border-gray-200 text-slate-950">Online Users</h3>
			<button class="block w-full p-2 text-left hover:bg-gray-200 text-slate-900" @click="joinRoom('all')">
				Global Chat
			</button>
			<ul class="divide-y divide-gray-200">
				<li v-for="user in onlineUsers" :key="user.username" class="px-4 py-2 text-cyan-900">
					<a class="cursor-pointer" @click="joinChat(user.username)">{{ user.username }}</a>
				</li>
			</ul>
		</div>

		<!-- Chat Box -->
		<div class="flex-1 flex flex-col">
			<div ref="chatBox" class="flex-1 p-4 overflow-y-auto">
				<div v-for="(message, index) in currentRoomMessages" :key="index" class="mb-2">
					<div class="flex items-center">
						<div class="font-semibold mr-2">{{ message.from }}</div>
						<div class="bg-gray-200 rounded-lg p-2">{{ message.text }}</div>
					</div>
				</div>
			</div>

			<!-- Message Input -->
			<div class="p-4 border-t border-gray-200">
				<div class="flex">
					<a-input
						v-model:value="messageText"
						placeholder="Type your message..."
						class="flex-1 p-2 border border-gray-300 rounded-l-lg text-slate-900"
						@keyup.enter="sendMessage"
					/>
					<button class="px-4 py-2 bg-blue-500 text-white rounded-r-lg ml-2" @click="sendMessage">Send</button>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
	import { ref, onMounted, watch, nextTick } from 'vue'
	import localforage from 'localforage'
	import { useUserStore } from '@/store/user'

	interface Message {
		from: string
		text: string
	}

	interface User {
		username: string
	}

	const userStore = useUserStore()
	const currentTo = ref<string>('all')
	const currentType = ref<string>('room')
	const currentRoomMessages = ref<Message[]>([])

	const onlineUsers = ref<User[]>([])
	const messageText = ref<string>('')

	const chatBox = ref<HTMLElement | null>(null)

	let ws: WebSocket
	const username = ref<string>('')
	const userId = Math.floor(Math.random() * 1000)

	function joinRoom(room: string) {
		currentTo.value = room
		currentType.value = 'room'
	}

	function joinChat(username: string) {
		currentTo.value = username
		currentType.value = 'chat'
	}

	function onMessage(event: MessageEvent) {
		const data = JSON.parse(event.data)
		let message: Message = {
			from: '',
			text: '',
		}
		// console.log(currentTo.value, currentType.value)
		switch (data.type) {
			case 'online': {
				onlineUsers.value = data.users
				break
			}
			case 'room': {
				//{ room,from,text }
				message.from = data.from
				message.text = data.text
				if (data.room === currentTo.value) {
					currentRoomMessages.value.push(message)
				}
				const key = `room:${data.room}`
				localforage.getItem(key).then((data) => {
					if (data == null) {
						data = []
					}
					data.push(message)
					localforage.setItem(key, data)
				})
				break
			}
			case 'chat': {
				//{ from,text }
				message.from = data.from
				message.text = data.text
				if (data.from === currentTo.value) {
					currentRoomMessages.value.push(message)
				}
				const key = `chat:${message.from}`
				localforage.getItem(key).then((data) => {
					if (data == null) {
						data = []
					}
					data.push(message)
					localforage.setItem(key, data)
				})
				break
			}
			default:
				break
		}
	}

	function sendMessage() {
		const sendMessage = {
			type: currentType.value,
			text: messageText.value,
			to: currentTo.value,
		}
		ws.send(JSON.stringify(sendMessage))
		if (currentType.value === 'chat') {
			let message: Message = {
				from: sendMessage.to,
				text: sendMessage.text,
			}

			const key = `chat:${message.from}`
			localforage.getItem(key).then((data) => {
				if (data == null) {
					data = []
				}
				data.push(message)
				localforage.setItem(key, data)
			})
			message.from = username.value
			if (sendMessage.to === currentTo.value) {
				currentRoomMessages.value.push(message)
			}
		}
		messageText.value = ''
	}

	function getUsername() {
		username.value = userStore.getChatUsername()
		// console.log(username.value)
		if (!username.value) {
			username.value = `Guest${userId}`
			// console.log(username.value)
			userStore.setChatUsername(username.value)
		}
	}

	const connectWebSocket = () => {
		ws = new WebSocket(`ws://localhost:4433/websocket/${username.value}`)
		ws.onmessage = onMessage
		ws.onclose = () => {
			console.log('WebSocket closed. Reconnecting...')
			setTimeout(connectWebSocket, 1000) // 延迟 1 秒后重新连接
		}
	}
	onMounted(() => {
		// Connect to WebSocket
		getUsername()
		connectWebSocket()
		localforage.getItem(`room:all`).then((data) => {
			if (data != null) {
				currentRoomMessages.value = data
			}
		})
	})

	watch([currentTo, currentType], ([newTo, newType], [oldTo, oldType]) => {
		const key = `${oldType}:${oldTo}`
		localforage.setItem(key, currentRoomMessages.value)

		const newKey = `${newType}:${newTo}`
		localforage.getItem(newKey).then((data) => {
			if (data) {
				currentRoomMessages.value = data
			} else {
				currentRoomMessages.value = []
			}
		})
	}) //

	watch(currentRoomMessages, () => {
		nextTick(() => {
			if (chatBox.value) {
				chatBox.value.scrollTop = chatBox.value.scrollHeight
			}
		})
	})
</script>

<style scoped>
	/* Add scoped styles here if needed */
</style>
